package com.example.myapplication;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {
    private final static String TAG = "MainActivity";
    private UUID UUID_SERVICE = UUID.fromString("0000fff0-0000-1000-8000-00805f9b34fb");
    private UUID UUID_CHARACTERISTIC_NOTIFY = UUID.fromString("0000fff1-0000-1000-8000-00805f9b34fb");
    private UUID UUID_CHARACTERISTIC_WRITE = UUID.fromString("0000fff2-0000-1000-8000-00805f9b34fb");
    private static final UUID CLIENT_CHARACTERISTIC_CONFIG_UUID = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
    private BluetoothManager bluetoothManager;
    private BluetoothAdapter bluetoothAdapter;
    private BluetoothLeScanner bluetoothLeScanner;
    private BluetoothGatt bluetoothGatt;
    private final static int REQUEST_ENABLE_BT = 1;
    private final static int DEFAULT_MTU = 23;
    private final static int REQUEST_MTU = 247; // Maximum MTU size for BLE
    private BluetoothGattCharacteristic mCharacteristic_notify;
    private BluetoothGattCharacteristic mCharacteristic_write;
    private String targetDeviceName = "HLK-LD2410"; // 设置目标设备名称
    //private String targetDeviceAddress = "XX:XX:XX:XX:XX:XX"; // 设置目标设备MAC地址

    private Button button1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);

        getPersimmions();
        bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        bluetoothAdapter = bluetoothManager.getAdapter();
        if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
        }
        startScan();

        button1 = findViewById(R.id.btn_1);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });
    }

    private void getPersimmions() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            ArrayList<String> permissions = new ArrayList<String>();
            /***
             * 定位权限为必须权限，用户如果禁止，则每次进入都会申请
             */
            // 定位精确位置
            if (checkSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                permissions.add(android.Manifest.permission.ACCESS_FINE_LOCATION);
            }
            if (checkSelfPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                permissions.add(android.Manifest.permission.ACCESS_COARSE_LOCATION);
            }
            if(checkSelfPermission(android.Manifest.permission.BLUETOOTH_SCAN)!=PackageManager.PERMISSION_GRANTED){
                permissions.add(android.Manifest.permission.BLUETOOTH_SCAN);
            }
            if(checkSelfPermission(android.Manifest.permission.BLUETOOTH_CONNECT)!=PackageManager.PERMISSION_GRANTED){
                permissions.add(android.Manifest.permission.BLUETOOTH_CONNECT);
            }
        }
    }
    public void startScan() {
        if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
            Log.e(TAG, "Bluetooth not enabled");
            return;
        }

        bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
        ScanSettings scanSettings = new ScanSettings.Builder()
                .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                .build();

        // 设置扫描过滤器（可选）
        List<ScanFilter> scanFilters = new ArrayList<>();

//        if (targetDeviceName != null) {
//            ScanFilter nameFilter = new ScanFilter.Builder()
//                    .setDeviceName(targetDeviceName)
//                    .build();
//            scanFilters.add(nameFilter);
//        }

        bluetoothLeScanner.startScan(scanFilters, scanSettings, scanCallback);
    }

    public void stopScan() {
        if (bluetoothLeScanner != null) {
            bluetoothLeScanner.stopScan(scanCallback);
        }
    }

    private final ScanCallback scanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            super.onScanResult(callbackType, result);
            BluetoothDevice device = result.getDevice();
            String deviceName = device.getName();
            String deviceAddress = device.getAddress();
            Log.d(TAG, "Found device: " + deviceName + " - " + deviceAddress);

            // 过滤设备：根据名称和MAC地址
            if (deviceName!=null && deviceName.contains(targetDeviceName)){
                Log.d(TAG, "Found target device by name: " + deviceName);
                connectToDevice(device);
            }
        }

        @Override
        public void onScanFailed(int errorCode) {
            super.onScanFailed(errorCode);
            Log.e(TAG, "Scan failed with error code: " + errorCode);
        }
    };

    private void connectToDevice(BluetoothDevice device) {
        // 停止扫描
        stopScan();
        // 连接设备
        bluetoothGatt = device.connectGatt(MainActivity.this, true, gattCallback);
    }

    private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            super.onConnectionStateChange(gatt, status, newState);
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                Log.d(TAG, "Connected to GATT server.");
                // 发现服务
                gatt.discoverServices();
            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                Log.d(TAG, "Disconnected from GATT server.");
            }
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            super.onServicesDiscovered(gatt, status);
            if (status == BluetoothGatt.GATT_SUCCESS) {
                Log.d(TAG, "Services discovered.");
                List<BluetoothGattService> services = gatt.getServices();
                for (BluetoothGattService service : services) {
                    Log.d(TAG, "Service UUID: " + service.getUuid().toString());
                }

                // Request MTU update
                gatt.requestMtu(REQUEST_MTU);

                // Enable notifications for a specific characteristic
                BluetoothGattService service = gatt.getService(UUID_SERVICE);
                if (service != null) {
                    try {
                        mCharacteristic_notify = service.getCharacteristic(UUID_CHARACTERISTIC_NOTIFY);
                        Thread.sleep(1000);
                        mCharacteristic_write = service.getCharacteristic(UUID_CHARACTERISTIC_WRITE);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }

                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                if(mCharacteristic_notify!=null){
                                    enableNotifications(gatt, mCharacteristic_notify);
                                }
                                Thread.sleep(2000);
                                // 获取蓝牙权限
                                getRadarBlePremission();
                            } catch (InterruptedException e) {
                                throw new RuntimeException(e);
                            }
                        }
                    }).start();
                }
            }
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicRead(gatt, characteristic, status);
            if (status == BluetoothGatt.GATT_SUCCESS) {
                byte[] data = characteristic.getValue();
                Log.d(TAG, "Characteristic value: " + Arrays.toString(data));
            }
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicChanged(gatt, characteristic);
            byte[] data = characteristic.getValue();
            //Log.d(TAG, "Received notification: " + bytesToHexString(data));
            if (mHandler != null) {
                Message msg = Message.obtain();
                msg.obj = data;
                msg.arg1 = data.length;
                msg.what = 1;
                mHandler.sendMessage(msg);
            }
        }

        @Override
        public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
            super.onMtuChanged(gatt, mtu, status);
            if (status == BluetoothGatt.GATT_SUCCESS) {
                Log.d(TAG, "MTU changed to: " + mtu);
            }
        }
    };

    private void enableNotifications(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
        gatt.setCharacteristicNotification(characteristic, true);

        BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG_UUID);
        if (descriptor != null) {
            descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
            gatt.writeDescriptor(descriptor);
        }
    }

    /**
     * 获取蓝牙权限，参考《LD2410B 串口通讯协议2.2.14》
     */
    public void getRadarBlePremission()
    {
        if(mCharacteristic_write==null) {
            return;
        }
        String bleKey = "FDFCFBFA0800A80048694C696E6B04030201";
        Log.d(TAG,"write   "+bleKey);
        byte[] byt = hexToByteArray(bleKey);
        mCharacteristic_write.setValue(byt);
        bluetoothGatt.writeCharacteristic(mCharacteristic_write);
    }

    /**
     * 打开工程模式，参考《LD2410B 串口通讯协议2.2.5》
     */
    public void openProgramMode()
    {
        if(mCharacteristic_write==null) {
            return;
        }
        String str1 = "FDFCFBFA0400FF00010004030201";// 进入配置模式
        String str2 = "FDFCFBFA0200620004030201";// 使能工程模式
        String str3 = "FDFCFBFA0200FE0004030201";// 退出配置模式
        byte[] byt1 = hexToByteArray(str1);
        byte[] byt2 = hexToByteArray(str2);
        byte[] byt3 = hexToByteArray(str3);

        try {
            mCharacteristic_write.setValue(byt1);
            bluetoothGatt.writeCharacteristic(mCharacteristic_write);
            Thread.sleep(100);
            mCharacteristic_write.setValue(byt2);
            bluetoothGatt.writeCharacteristic(mCharacteristic_write);
            Thread.sleep(100);
            mCharacteristic_write.setValue(byt3);
            bluetoothGatt.writeCharacteristic(mCharacteristic_write);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * byte数组转16进制字符串
     * @param bArray
     * @return
     */
    public String bytesToHexString(byte[] bArray) {
        StringBuffer sb = new StringBuffer(bArray.length);
        String sTemp;
        for (int i = 0; i < bArray.length; i++) {
            sTemp = Integer.toHexString(0xFF & bArray[i]);
            if (sTemp.length() < 2)
                sb.append(0);
            sb.append(sTemp.toUpperCase());
        }
        return sb.toString();
    }

    /**
     * hex字符串转byte数组
     * @param inHex 待转换的Hex字符串
     * @return  转换后的byte数组结果
     */
    public static byte[] hexToByteArray(String inHex){
        int hexlen = inHex.length();
        byte[] result;
        if (hexlen % 2 == 1){
            //奇数
            hexlen++;
            result = new byte[(hexlen/2)];
            inHex="0"+inHex;
        }else {
            //偶数
            result = new byte[(hexlen/2)];
        }
        int j=0;
        for (int i = 0; i < hexlen; i+=2){
            result[j]=hexToByte(inHex.substring(i,i+2));
            j++;
        }
        return result;
    }
    /**
     * Hex字符串转byte
     * @param inHex 待转换的Hex字符串
     * @return  转换后的byte
     */
    public static byte hexToByte(String inHex){
        return (byte)Integer.parseInt(inHex,16);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (bluetoothGatt != null) {
            bluetoothGatt.disconnect();
            bluetoothGatt.close();
            bluetoothGatt = null;
        }
    }

    public Handler mHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            byte[] data = (byte[]) msg.obj;
            int len = msg.arg1;
            switch (msg.what) {
                case 1:{
                    Log.d(TAG,"len = "+len);
                    //Log.d(TAG,bytesToHexString(Arrays.copyOfRange(data,0,len))+"  ");
                    String str = bytesToHexString(data);
                    if(str.contains("F4F3F2F1") && data[6]==0x02){// 工程模式
                        openProgramMode();
                    }else if(str.contains("F4F3F2F1") && data[6]==0x01){//目标数据模式
                        if(data[38] == 1) {
                            Log.d(TAG, data[38] + "   有人");
                        }else{
                            Log.d(TAG, data[38] + "   无人");
                        }
                    }
                }break;
            }
        }
    };
}